<?php

namespace app\api\controller;

class Geo extends Common
{

    public function index()
    {
        $lon = input('post.lon/f');
        $lat = input('post.lat/f');
        return $this->findCity($lon, $lat);
    }


    /**
     * 判断点是否在多边形内
     * @param float $lon 经度
     * @param float $lat 纬度
     * @param array $polygon 多边形坐标数组
     * @return bool
     */
    protected function isPointInPolygon($lon, $lat, $polygon)
    {
        $inside = false;
        $points = count($polygon);
        for ($i = 0, $j = $points - 1; $i < $points; $j = $i++) {
            $xi = $polygon[$i][0];
            $yi = $polygon[$i][1];
            $xj = $polygon[$j][0];
            $yj = $polygon[$j][1];

            $intersect = (($yi > $lat) != ($yj > $lat)) &&
                ($lon < ($xj - $xi) * ($lat - $yi) / ($yj - $yi + 1e-10) + $xi);
            if ($intersect) {
                $inside = !$inside;
            }
        }
        return $inside;
    }

    /**
     * 根据坐标查找所属城市
     * @param float $lon 经度
     * @param float $lat 纬度
     * @param string $geojsonFile GeoJSON 文件路径
     * @return string|null
     */
    public function findCity($lon = null, $lat = null)
    {
        // 示例参数

        if (!$lon || !$lat) {
            return json(['error' => '缺少经纬度参数'], 400);
        }

        $geojsonFile = ROOT_PATH . 'public/china_city.json';

        if (!file_exists($geojsonFile)) {
            return json(['error' => 'GeoJSON 文件不存在'], 500);
        }

        $geojson = json_decode(file_get_contents($geojsonFile), true);
        foreach ($geojson['features'] as $feature) {
            $geometry = $feature['geometry'];
            $coordinates = $geometry['coordinates'];
            $type = $geometry['type'];
            $name = $feature['properties']['name'] ?? '北京';

            if ($type === 'Polygon') {
                foreach ($coordinates as $polygon) {
                    if ($this->isPointInPolygon($lon, $lat, $polygon)) {
                        return json(['city' => $name]);
                    }
                }
            } elseif ($type === 'MultiPolygon') {
                foreach ($coordinates as $multiPolygon) {
                    foreach ($multiPolygon as $polygon) {
                        if ($this->isPointInPolygon($lon, $lat, $polygon)) {
                            return json(['city' => $name]);
                        }
                    }
                }
            }
        }

        return json(['city' => null]);
    }
}
